<?php

/**
 * HTML Helper
 * Contains many static methods for generating existing and advanced html components (tags)
 *
 * @static 
 * @author Ben Rowe
 */
class HTMLHelper
{
	/**
	 * Generates a button tag (with optional 16x16 png icon)
	 *
	 * @static 
	 * @access public
	 * @param string $label Name of button (displayed within button)
	 * @param string $icon icon filename (without extension)
	 * @param boolean $type hilite the button green or red
	 * @param string $btnType (button or submit)
	 * @return string
	 */
	function button($label, $className, $icon = false, $type = null, $btnType = 'button')
	{
		// if a type is specified generate the proper string value for it
		$type = (is_bool($type)) ? ($type ? 'positive' : 'negative') : $type;
		$html = '<button type="'.$btnType.'" class="'.$className.' '.$type.'">';
		if($icon) {
			$html .= HTMLHelper::icon($icon, $label);
		}
		$html .= $label.'</button>';
		return $html; 
	}
	
	/**
	 * Generates a button tag, but using an anchor (to redirect to a specific url
	 *
	 * @static 
	 * @access public
	 * @param string $label
	 * @param string $url
	 * @param string $icon
	 * @param boolean $type
	 * @param string $className
	 * @return string
	 */
	function btnAnchor($label, $url, $icon = false, $type = null, $className = false)
	{
		$class = 'button';
		if($icon) {
			$label = HTMLHelper::icon($icon, $label). $label;
		}
		if(is_bool($type)) {
			$class .= ($type) ? ' positive' : ' negative';
		}
		
		if($className) {
			// the className should go at the front of the class attribute
			$class = $className.' '.$class;
		}
		return HTMLHelper::anchor($label, $url, $class);
	}
	
	/**
	 * Creates a icon styled like a button (with no button label as such)
	 *
	 * @static 
	 * @access public
	 * @param string $icon
	 * @param string $className
	 * @param string $alt
	 * @return string
	 */
	function btnIcon($icon, $className, $alt)
	{
		return '<div class="'.$className.' button-icon">'.HTMLHelper::icon($icon, $alt).'</div>';
	}
	
	/**
	 * Predefined image tag for displaying 16x16 png icons from the icons folder
	 *
	 * @static 
	 * @access public
	 * @param string $icon name without the extension value (because only png files are allowed)
	 * @param string $alt alternate value for the image if the file can not be loaded
	 * @return string
	 */
	function icon($icon, $alt = '')
	{
		return HTMLHelper::image('icons/'.$icon.'.png', $alt, 'class="icon"');
	}
	
	/**
	 * Generates a standard image tag
	 *
	 * @static 
	 * @access public
	 * @param string $src
	 * @param string $alt
	 * @param string $attributes
	 * @return string
	 */
	function image($src, $alt = '', $attributes = '')
	{
		return '<img src="public/images/'.$src.'" alt="'.$alt.'" '.$attributes.' />';
	}

	/**
	 * Generates an anchor tag
	 *
	 * @static 
	 * @access public
	 * @param string $label
	 * @param string $href
	 * @param string $class
	 * @param string $accesskey
	 * @return string
	 */
	function anchor($label, $href = 'index.php', $class = null, $accesskey = null)
	{
		if(preg_match('/^(section|action)/i', $href)) {
			$href = 'index.php?'.$href;
		}
		// htmlentities the href
		$href = preg_replace("/(&|&amp;)/", '&amp;', $href);
		return '<a href="'.$href.'" class="'.$class.'" accesskey="'.$accesskey.'">'.$label.'</a>';
	}

	/**
	 * Generates a form tag
	 * if the form is posted, and the action query string is provided, then it is broken up and placed into hidden fields
	 *
	 * @static
	 * @access public
	 * @param string $action (query string)
	 * @param string $method
	 * @return string
	 */
	function form($action = '', $method = 'post', $enctypeUpload = false, $attributes = '') 
	{
		if($enctypeUpload) {
			$method = 'post'; // method MUST be post regardless!
			$enctypeUpload = 'enctype="multipart/form-data"';
		} else {
			$enctypeUpload = '';
		}
		//$qs = ($method == 'get' && !empty($action)) ? '?'.str_replace('&', '&amp;', $action) : null;
		$html = '<form method="'.$method.'" action="index.php" '.$enctypeUpload.' '.$attributes.'>';
		if(!empty($action)) {
			$html .= '<div class="hidden">';
			$parts = explode('&', $action);
			foreach($parts as $part) {
				if(!empty($part)) { // ensure that the part is not empty! could occur if the $action starts with a &
					$tmp = explode('=', $part, 2);
					$html .= HTMLHelper::hidden($tmp[0], $tmp[1]);
				}
			}
			$html .= '</div>';
		}
		return $html;
	}
	
	/**
	 * Generates a single hidden input field
	 *
	 * @static
	 * @access public
	 * @param string $name
	 * @param string $value
	 * @return string
	 */
	function hidden($name, $value = '')
	{
		return '<input type="hidden" name="'.$name.'" value="'.$value.'" />';
	}
	
	/**
	 * Generates several hidden input fields based on an associated array
	 * Handles multi-dimentional arrays
	 *
	 * @static 
	 * @access public
	 * @param array $data
	 * @return string
	 */
	function hiddenArray($data, $namePrefix = null)
	{
		$html = null;
		foreach($data as $name=>$value) {
			if(is_array($value)) {
				$name = $namePrefix != null ? $namePrefix.'['.$name.']' : $name;
				$html .= HTMLHelper::hiddenArray($value, $name);
			} else {
				$name = $namePrefix != null ? $namePrefix.'['.$name.']' : $name;
				$html .= HTMLHelper::hidden($name, $value);
			}
		}
		return $html;
	}
	
	/**
	 * Generates a multi-line text input
	 *
	 * @static 
	 * @access public
	 * @param string $name name of element
	 * @param string $value initial value
	 * @return string
	 */
	function textarea($name, $value = '')
	{
		return '<textarea name="'.$name.'" rows="8" cols="50">'.$value.'</textarea>';
	}
	
	/**
	 * Generates a single line text input
	 *
	 * @static 
	 * @access public
	 * @param string $name name of element
	 * @param string $value initial value
	 * @return string
	 */
	function textinput($name, $value = '', $class = '', $attributes = '')
	{
		$class = 'text'.(!empty($class) ? ' '.$class : null);
		return '<input type="text" class="'.$class.'" name="'.$name.'" value="'.$value.'" '.$attributes.' />';
	}
	
	/**
	 * Generate a single checkbox
	 *
	 * @static
	 * @access public 
	 * @param string $name name of element
	 * @param string $value initial value
	 * @param boolean $checked checked state
	 * @return unknown
	 */
	function checkbox($name, $value = '', $checked = false)
	{
		$checked = $checked ? 'checked="checked"' : null;
		return '<input type="checkbox" name="'.$name.'" value="'.$value.'" '.$checked.' />';
	}
	
	/**
	 * Generate a single radio box element
	 *
	 * @static 
	 * @access public
	 * @param string $name name of element
	 * @param string $value 
	 * @param boolean $checked checked state
	 * @return string
	 */
	function radio($name, $value, $checked = false)
	{
		$checked = $checked ? 'checked="checked"' : null;
		return '<input type="radio" name="'.$name.'" value="'.$value.'" '.$checked.' />';
	}
	
	/**
	 * Generate a file selection element
	 *
	 * @static 
	 * @access public
	 * @param string $name name of element
	 * @return string
	 */
	function file($name)
	{
		return '<input type="file" name="'.$name.'" />';
	}
	
	/**
	 * Generate a select/drop down list
	 *
	 * @static 
	 * @access public
	 * @param string $name
	 * @param ListItemCollection $values
	 * @param string $checked
	 * @param string $attributes
	 * @return string
	 */
	function select($name, $values = false, $checked = false, $attributes = '')
	{
		$html = '<select name="'.$name.'" '.$attributes.'>';
		if(is_a($values, 'ListItemCollection')) {
			$items = $values->getItems();
			foreach($items as $item) {
				$html .= HTMLHelper::_option($item->getValue(), $item->getLabel(), ($checked == $item->getValue()));
			}
		}
		$html .= '</select>';
		return $html;
	}
	
	/**
	 * Generate an <option> tag for a <select> list
	 *
	 * @static 
	 * @access private
	 * @param string $value
	 * @param string $label
	 * @param label $selected
	 * @return string
	 */
	function _option($value, $label, $selected = false)
	{
		$selected = $selected ? ' selected="selected"' : null;
		return '<option value="'.$value.'"'.$selected.'>'.$label.'</option>';
	}
	
	/**
	 * Generate a list of related radio selection boxes
	 *
	 * @static 
	 * @access public
	 * @param string $name
	 * @param ListItemCollection $values
	 * @param string $checked
	 * @return string
	 */
	function radioGroup($name, $values = false, $checked = false)
	{
		$html = '<ul class="radio-group">';
		if(is_a($values, 'ListItemCollection')) {
			$items = $values->getItems();
			foreach($items as $item) {
				$html .= '<li><label>'.HTMLHelper::radio($name, $item->getValue(), ($item->getValue() == $checked)).$item->getLabel().'</label></li>';
			}
		}
		
		$html .= '</ul>';
		return $html;
	}
	
	/**
	 *Generate a list of related checkboxes
	 *
	 * @static 
	 * @access public
	 * @param string $name
	 * @param ListItemCollection $values
	 * @param string $checked
	 * @return string
	 */
	function checkboxGroup($name, $values = false, $checked = false)
	{
		// if the name doesnt end with a [], then add it!
		if(!preg_match('/\[\]$/', $name)) {
			// forces a php array for multiple options
			$name .= '[]';
		}
		$html = '<ul class="checkbox-group">';
		if(is_a($values, 'ListItemCollection')) {
			$items = $values->getItems();
			foreach($items as $item) {
				$html .= '<li><label>'.HTMLHelper::checkbox($name, $item->getValue(), ($item->getValue() == $checked)).$item->getLabel().'</label></li>';
			}
		}
		
		$html .= '</ul>';
		return $html;
	}
	
	/**
	 * Generate a password input field
	 *
	 * @static 
	 * @access public
	 * @param string $name
	 * @return string
	 */
	function password($name)
	{
		return '<input type="password" name="'.$name.'" value="" class="text" />';
	}
	
	/**
	 * Checks the formatting of the supplied attributes string and 
	 * returns a string that contains only valid attributes. Any 
	 * INVALID attributes are simply droped
	 *
	 * @todo implement this functionality
	 * @static 
	 * @access private
	 * @param unknown_type $attributes
	 * @return unknown
	 */
	function _validateAttributesString($attributes)
	{
		
	}
	
	/**
	 * Generate a sgml element
	 *
	 * @static 
	 * @access private
	 * @param string $name
	 * @param mixed $attributes
	 * @param boolean $closeTag
	 * @return string
	 */
	function element($name, $attributes = array(), $closeTag = false)
	{
		return '<'.$name.HTMLHelper::_attributes($attributes).($closeTag ? '/' : null).'>';
	}
	
	/**
	 * Convert an array of key/values into a valid sgml argument string
	 *
	 * @static 
	 * @access private
	 * @param mixed $options
	 * @return string
	 */
	function _attributes($options)
	{
		if(is_array($options)) {
			// build the attributes from an array
		} else {
			return $this->_validateAttributesString($options);
		}
	}
	
}

?>